01. 협력하는 객체들의 공동체
📌 Contents
📌 실세계의 객체와 소프트웨어의 객체는 대응되는가?
- 실세계의 모방이라는 개념은 객체지향의 기반을 이루는 철학적인 개념을 설명하는 데는 적합함.
- 하지만, 유연하고 실용적인 관점에서 객체지향 분석, 설계를 설명하기에는 적합하지 않음.
- 객체의 직접적으로 대응되는 실세게의 사물을 발견할 확률은 높지 않음.
- 발견한다 해도 객체와 사물 간의 개념적 거리는 매우 멈.
ex) 실제 방화벽과 소프트웨어 방화벽 - 객체지향의 목표는 실세계를 모방하는 것이 아니라 새로운 세계를 창조하는 것.
- 그럼에도 많은 사람들이 소프트웨어의 객체를 실세계의 객체에 대응하는 이유는 객체지향의 다양한 측면을 이해하고 학습하는 데 매우 효과적이기 때문.
- 소프트웨어의 객체를 실세계의 객체에 대응한다면,
상태와 행위를 캡슐화
하는 소프트웨어 객체의자율성
을 설명하는 데 효과적- 메세지를 주고받으며 공동의 목표를 달성하기 위해
협력하는 객체들의 관계
를 설명하는데 적합 - 객체지향 설계의 핵심 사상인
연결완전성
을 설명하는데 적합
Note
실세계의 객체에 대응은 문제 해결방법으로서의 실용적 측면에서는 좋지 않지만, 객체지향이라는 세계를 이해하는 데에는 도움이 된다.
📌 소프트웨어의 객체를 실세계의 객체에 대응해 보자.
- 한 회사원이 카페에 가서 아메리카노를 주문하는 상황을 떠올려 보자.
- 회사원은 손님으로서 카페에 들어간 뒤 캐시어에게 가서 아메리카노를 주문할 것이다.
- 캐시어는 바리스타를 향해 주문받은 컵을 놓을 것이다.
- 바리스타는 자신의 차례를 기다리는 컵을 들어 주문내역을 본 뒤 커피를 만들 것이다.
- 바리스타가 커피가 채워진 컵을 테이블에 올려 두면 캐시어는 손님에게 알릴 것이다.
- 손님은 커피를 들고 카페를 나갈 것이다.
- 이 상황에서 3개의
역할
이 존재한다. 손님, 캐시어, 바리스타 - 각각의 역할은 자신의
책임
을 가지고 있을 것이다. 손님 - 커피 주문, 캐시어 - 주문 받기, 바리스타 - 커피 제조 - 이러한 상황에서 각각의 사람들이 자신의 역할과 책임을 다하면서 서로간의 암묵적인
협력
이 존재한다.
Note
실생활에서 일어나는 커피 주문이라는 상황에서 객체지향에서 가장 중요한 개념인 역할, 책임, 협력
을 이해할 수 있다.
📌 실생활에서의 역할, 책임, 협력
협력
은 요청과 응답으로 구성된다.- 손님 -> 캐시어: 커피를 주문한다 (요청)
- 캐시어 -> 바리스타: 커피를 제조하라 (요청)
- 바리스타 -> 캐시어: 커피 완성 (응답)
- 캐시어 -> 손님: 커피 완성 (응답)
역할
은책임
이라는 개념을 내포한다.- 선생님: 학생을 가르칠 책임
- 경찰관: 범죄자를 검거할 책임
- 사람들은
협력
을 위해 특정한역할
을 맡고, 역할에 적합한책임
을 수행
- 여러 사람이 동일한 역할 수행 가능
: 손님이나 캐시어, 바리스타는 여러명일 수 있음. - 역할은 대체 가능성을 의미
: 손님 입장에서 캐시어는 대체 가능. 어떤 캐시어가 역할을 수행하든 문제 없음. - 책임을 수행하는 방법은 자율적으로 선택 가능
: 커피를 만드는 방식은 바리스타마다 다름 - 한 사람이 동시에 여러 역할 수행 가능
: 주문을 받는 사람이 커피도 만든다면, 캐시어이면서 바리스타라고 할 수 있음.
Note
실생활에서 목표는 사람들의 협력
을 통해 달성되며, 목표는 더 작은 책임
으로 분할되고 책임을 수행할 수 있는 적적한 역할
을 가진 사람에 의해 수행된다.
📌 소프트웨어 객체에서의 역할, 책임, 협력
- 객체의 세계도 인간의 세계와 유사.
사람 -> 객체, 요청 -> 메시지, 요청을 처리하는 방법 -> 메서드 - 객체는 자신에게 주어진
역할
과책임
을 다하는 동시에 다른 객체와도 적극적으로협력
- 시스템의 기능은 객체들이 성실히 협력해서 일궈낸 결실
- 객체지향 설계라는 예술은 적절한 객체에 적절한 책임을 할당하는 것에서 시작
- 책임은 객체지향 설계의 품질을 결정하는 가장 중요한 요소
- 역할은 유연하고 재사용 가능한 협력 관계를 구축하는데 중요한 설계 요소
- 여러 객체가 동일한 역할 수행 가능
- 역할은 대체 가능성을 의미
- 각 객체는 책임을 수행하는 방법을 자율적으로 선택 가능
- 하나의 객체가 동시에 여러 역할 수행 가능
Note
객체의 적절한 역할
과 적절한 책임
, 목표를 달성하기 위한 적절한 협력
은 애플리케이션의 아름다움을 결정
📌 자율성을 가진 채 서로 협력하는 객체들
- 실제로 협력에 참여하는 주체는 객체
- 객체가 존재하지 않는 객체지향 세계는 아무런 의미가 없음.
- 객체지향을 객체지향이라고 부르는 이유는 패러다임의 중심에 객체가 있기 때문
- 객체는 애플리케이션의 기능을 구현하기 위해 존재
- 아주 작은 기능조차 객체 혼자 감당하기 버거워 객체는 다른 객체와 협력을 통해 기능 구현
- 객체지향 애플리케이션의 아름다움을 결정하는 것이 협력이라면, 협력이 얼마나 조화를 이루는지 결정하는 것은 객체
- 협력 공동체의 일원으로서 객체는 두 가지 덕목을 갖춰야함.
- 객체는 충분히
협력적
이여야 함. - 객체는 충분히
자율적
이여야 함.
- 객체는 충분히
- 흔히 객체를
상태
와행동
을 함께 지닌 실체라고 정의 - 객체가 협력에 참여하기 위해 어떤 행동을 해야한다면 그 행동을 하는 데에 필요한 상태도 함께 지니고 있어야 함.
- 객체의 자율성이란 자신의 상태를 직접 관리하고 상태를 기반으로 스스로 판단하고 행동할 수 있음을 의미
- 바리스타는
커피 제조 방법(상태)
을 기억하는 동시에자신이 알고 있는 방법에 따라 커피를 제조(상태에 따른 행동)
함. 즉, 객체는 상태와 행위를 하나의 단위로 묶는 자율적인 존재
- 과거의 전통적인 개발 방법은 데이터와 프로세스를 엄격하게 구분하는데 이와 객체지향의 핵심적인 차이는 데이터와 프로세스를 하나의 틀 안에 묶어 놓음으로 서 객체의 자율성을 보장한 다는 것.
- 자율적인 객체로 구성된 공동체는 유지보수가 쉽고 재사용이 용이한 시스템을 구축할 수 있는 가능성을 제시
- 객체는 협력을 위해 다른 객체에게 메시지를 전송하고 다른 객체로부터 메시지를 수신
객체지향의 세계에서 협력
은 메시지를 전송하는 객체와 메시지를 수신하는 객체 사이의 관계로 구성
- 객체가 수신된 메시지를 처리하는 방법을
메서드
라고 부름 - 객체지향에서 메시지와 메서드는 분리되어 있음
- 메시지와 메서드의 분리는 객체의 협력에 참여하는 객체들 간의 자율성을 증진시킴.
- 이 처럼 메시지와 메서드의 분리는
캡슐화
라는 개념과도 깊이 관련되어 있음.
Note
객체들은 협력하는 과정에서 자신이 할 행동을 스스로 결정하고 책임지는 자율적인 존재
이다
객체지향 설계의 묘미는 다른 객체와 조화롭게 협력
할 수 있을 만큼 충분히 개방적인 동시에 협력에 참여하는 방법을 스스로 결정할 수 있을만큼 충분히 자율적
인 공동체를 설계하는 데 있다.
📌 객체지향의 본질
- 객체지향이란 시스템을 상호작용하는
자율적인 객체들의 공동체
로 바라보고 객체를 이용해 시스템을 분할하는 방법이다. - 자율적인 객체란
상태
와행위
를 함께 지니며 스스로 자기 자신을 책임지는 객체를 의미한다. - 객체는 시스템의 행위를 구현하기 위해 다른 객체와
협력
한다. 각 객체는 협력 내에서 정해진역할
을 수행하며 역할은 관련된책임
의 집합이다. - 객체는 다른 객체와 협력하기 위해
메시지
를 전송하고, 메시지를 수신한 객체는 메시지를 처리하는 데 적합한메서드
를 자율적으로 선택한다.
- 많은 사람들은 객체지향이라는 말을 들으면 클래스라는 단어를 떠올림
- 클래스가 객체지향 프로그래밍 언어의 관점에서 매우 중요한 구성요소이지만 핵심은 아님
- 자바스크립트는 클래스가 아닌 프로토타입을 이용해 객체지향 구현 가능
- 클래스의 관점에서 메시지를 주고받는 객체의 관점으로 사고의 중심을 전환하는 것이 중요
- 객체지향의 핵심은 클래스가 아니다
Note
클래스의 구조와 매서드가 아니라 객체의 역할
,책임
, 협력
에 집중하라.
객체지향은 객체를 지향하는 것이지 클래스를 지향하는 것이 아니다.
❓ Questions
❓ 객체지향에서의 역할, 책임, 협력의 정도는 어느정도로 설계되야 할까?
- 책에서 객체지향의 핵심은 역할, 책임, 협력이라고 나와있다.
- 한 객체가 여러 역할을 가질 수 있고, 한 역할을 여러 객체가 맡을 수도 있다. 또한 역할은 대체가 가능하다.
- 객체의 역할과 책임을 적절하게 잘 나누는 것이 객체지향 프로그래밍의 핵심이라고 하는데 역할과 책임을 어느정도로 나눠야 객체지향이라고 할 수 있을까?
- 하나의 객체가 자율성을 가지고 있다면 모든 역할과 책임을 다해도 객체지향이라고 할 수 있을까?
- 여러 역할을 한 객체가 맡는 것이 효율적이라 생각이 들어도 최대한 역할을 나누는 것이 객체지향이라고 할 수 있을까?
- 객체지향을 설계하는데에 있어 역할, 책임, 협력 적절히 나눠 설계하는 것은 매우 중요하다고 한다.
- 이를 위해 객체지향 설계에는 몇가지 원칙이 존재한다.
1. 단일 책임 원칙 (Single Responsibility Principle - SRP)
: 모든 클래스는 각각 하나의 책임만 가져야 한다.
2. 개방/폐쇄 원칙 (Open/Closed Principle - OCP)
: 기존의 코드를 변경하지 않으면서(Closed), 기능을 추가할 수 있도록(Open) 설계가 되어야 한다
3. 리스코프 치환 원칙 (Liskov Substitution Principle - LSP)
: 자식 클래스는 언제나 자신의 부모 클래스를 대체할 수 있다
4. 인터페이스 분리 원칙 (Interface Segregation Principle - ISP)
: 한 클래스는 자신이 사용하지않는 인터페이스는 구현하지 말아야 한다. 큰 인터페이스를 여러개의 작은 인터페이스로 분리하자.
5. 의존 역전 원칙 (Dependency Inversion Principle - DIP)
: 의존 관계를 맺을 때 변화하기 쉬운 것 또는 자주 변화하는 것보다는 변화하기 어려운 것, 거의 변화가 없는 것에 의존하라
- 이 5가지 원칙이 객체지향 설계 원칙 중 가장 많이 언급되는 SOLID 원칙이다.
- 아직 이 5가지 원칙에 대해 완벽하게 이해가 되지는 않지만 책을 끝까지 읽고 나면 이해가 될 수 있을까 기대된다.
❓ 연결완전성이란?
- 이 책에서 소프트웨어의 객체를 실세계의 객체에 대응한다면 다음과 같은 장점이 있다고 한다.
상태와 행위를 캡슐화
하는 소프트웨어 객체의자율성
을 설명하는 데 효과적- 메시지를 주고받으며 공동의 목표를 달성하기 위해
협력하는 객체들의 관계
를 설명하는데 적합 - 객체지향 설계의 핵심 사상인
연결완전성
을 설명하는데 적합
첫 번째와 두 번째 장점에 대해서는 책에서 계속 직접적으로 언급되는 설명이므로 이해하기 어렵지 않았다.
세 번째 장점에서 나오는 연결완전성에 대한 내용은 책에서 직접적으로 언급되지 않고, 이렇게만 언급이 된다.
실세계의 사물을 기반으로 소프트웨어 객체를 식별하고 구현까지 이어간다는 개념은 객체지향 설계의 핵심 사상인 연결완전성(seamlessness)을 설명하는데 적합한 틀을 제공한다.
연결완전성이란 무엇을 의미하는 것일까?
- 요청과 응답이 연쇄적으로 이루어지는 것을 연결완전성이라 하는 것 같다는 생각도 했다.
- "실세계의 사물을 기반으로 소프트웨어 객체를 식별하고 구현까지 이어간다는 개념" 이라는 부분을 보면 요청과 응답의 연쇄와 관련이 없는 것 같다.
- 실세계의 사물과 소프트웨어 객체의 대응과 관련이 있는 것 같은데 이 부분에 대해서는 책 6장에서 다시 다루는 것 같아 그 때 다시 생각해 봐야겠다.